package wubj.com.uploaddemo.upload;

import android.text.TextUtils;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.CoreConnectionPNames;
import org.apache.http.protocol.HTTP;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Date;
import java.util.Observable;

import wubj.com.uploaddemo.bean.ChatMsg;
import wubj.com.uploaddemo.utils.DateUtils;
import wubj.com.uploaddemo.utils.LogUtil;

public class UploadThread extends Observable implements Runnable {

    private static final String TAG = UploadThread.class.getSimpleName();

    private long downloaded; // already download size

    private int mNumber; // present downloaded task

    private long mCurrentDownloaded; // present task downloaded size

    private long size;

    public int status; // present download status

    private ChatMsg info = null; // need dowanload task

    private String id; // task id

    private float speed;// speed

    private long startTime = 0;

    private int endTime = 1;

    public boolean downType;

    public UploadThread(ChatMsg info, UploadManager manager) {
        downloaded = 0;
        status = DownConstants.START;
        this.info = info;
        mNumber = 0;
        mCurrentDownloaded = 0;
    }

    public long getId() {
        return info.msgId;
    }

    public int getCurrentNumber() {
        return mNumber;
    }

    public long getDownloaded() {
        return downloaded;
    }

    public ChatMsg getDownloads() {
        return info;
    }

    public ChatMsg getDownload() {
        return info;
    }

    public long getSize() {
        return size;
    }

    public float getProgress() {
        if (downloaded <= 0 || size <= 0) {
            return 0;
        } else {
            return ((float) downloaded / size) * 100;
        }

    }

    public float getSpeed() {

        int time = (int) (getTime() - startTime) / 1000;
        if (time != 0) {
            speed = downloaded / time;
        }
        return speed;
    }

    public int getStatus() {
        return status;
    }

    public void pause() {
        status = DownConstants.PAUSED;
        stateChanged();
    }

    public void resume() {
        status = DownConstants.DOWNLOADING;
        stateChanged();
        download();
    }

    public void cancel() {
        status = DownConstants.CANCELLED;
        stateChanged();
    }

    private void error() {
        status = DownConstants.ERROR;
        stateChanged();
    }

    private void download() {
        Thread thread = new Thread(this);
        thread.start();
    }

    private long getTime() {
        return new Date().getTime();
    }

    private long getFileSize(File file) throws Exception {
        long size = 0;
        if (file.exists()) {
            FileInputStream fis = null;
            fis = new FileInputStream(file);
            size = fis.available();
        } else {
            file.createNewFile();
            System.out.println("-----------------获取文件大小, 文件不存在!");
        }
        return size;
    }

    public void run() {
        OutputStream outputSteam = null;
        DataOutputStream dos = null;
        InputStream is = null;
        HttpURLConnection conn = null;

        try {
            startTime = getTime();
            File uploadFile = new File(info.imgPath);
            size = info.size;
            info.fileState = 1;
            stateChanged();
            conn = sendFile(info.uploadUrl);
            if (uploadFile.exists()) {
                outputSteam = conn.getOutputStream();
                dos = new DataOutputStream(outputSteam);
                dos.write("".getBytes());
                is = new FileInputStream(uploadFile);
                LogUtil.d(TAG, "wubaojie>>>run: isAvailable:" + is.available());
                byte[] bytes = new byte[2 * 1024];
                int len;
                while ((len = is.read(bytes)) != -1) {
                    dos.write(bytes, 0, len);
                    mCurrentDownloaded += len;
                    downloaded = mCurrentDownloaded;
                    stateChanged();
                }
                dos.flush();
                LogUtil.d(TAG, "wubaojie>>>run: dos.flush():");
                info.mContent = consume(conn.getContentLength(), conn.getInputStream());
                is.close();
                dos.close();
                LogUtil.d(TAG, "wubaojie>>>run: info.imgUrl:" + info.mContent);
                if (TextUtils.isEmpty(info.mContent)) {
                    info.fileState = 3;
                } else {
                    //提交接口数据
                    if (submitImg() == 0) {
                        info.fileState = 2;
                    } else {
                        info.fileState = 3;
                    }
                }

            }

            if (status == DownConstants.PAUSED || status == DownConstants.CANCELLED || status == DownConstants.ERROR) {
                info.fileState = 3;
                stateChanged();
            }
            mCurrentDownloaded = 0;
            mNumber++;

        } catch (Exception e) {
            e.printStackTrace();
            info.fileState = 3;
            error();
        } finally {
            if (conn != null) {
                try {
                    conn.disconnect();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            if (status == DownConstants.DOWNLOADING) {
                status = DownConstants.COMPLETE;
                stateChanged();
            }
        }
    }

    private byte[] buff = new byte[1024 * 15];

    private String consume(int contentLength, InputStream dis) throws IOException {
        byte[] result;
        if (contentLength == -1) {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            while (true) {
                int len = dis.read(buff, 0, buff.length);
                if (len == -1)
                    break;
                baos.write(buff, 0, len);
            }
            result = baos.toByteArray();
            baos.close();
            dis.close();
            baos = null;
        } else {
            result = new byte[contentLength];
            int currLen = 0;
            while (currLen < contentLength) {
                int len = dis.read(result, currLen, contentLength - currLen);
                if (len == -1)
                    break;
                currLen += len;
            }
            dis.close();
            if (currLen < contentLength) {
                return null;
            }
        }
        try {
            String value = new String(result, "UTF-8");
            LogUtil.d(TAG, "wubaojie>>>consume: value:" + value);
            JSONObject json = new JSONObject(value);

            if ("0".equals(json.optString("code")) || json.optString("code").endsWith("00")) {
                /*if (json.has("desc")) {
                    return json.optString("desc");
                } else*/
                if (json.has("msgList")) {
                    return json.optString("msgList");
                } else if (json.has("data")) {
                    return json.optString("data");
                } else if (json.has("desc")) {
                    return json.optString("desc");
                }
            } else {
                return "";
            }

        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
        return "";
    }

    public HttpURLConnection sendFile(String requestURL) throws IOException {
        HttpURLConnection conn = null;
        LogUtil.d(TAG, "wubaojie>>>sendFile: url >>>  " + requestURL);
        try {
            String filename = info.msgId + "." + info.fileType;
            if (info.fileName.lastIndexOf(".") != -1) {
                int index = info.fileName.lastIndexOf(".");
                filename = info.msgId + info.fileName.substring(index, info.fileName.length());
            }
            String urlStr;
            if (requestURL.lastIndexOf("?") != -1) {
                urlStr = requestURL + "&user_id=" + info.fromUser + "&file_type=" + info.mFileType + "&file_name=" +
                        filename;
            } else {
                urlStr = requestURL + "?user_id=" + info.fromUser + "&file_type=" + info.mFileType + "&file_name=" +
                        filename;

            }
            String picShootTime = "";
            if (!TextUtils.isEmpty(info.picShootTime)) {
                picShootTime = DateUtils.dateToString(new Date(Long.parseLong(info.picShootTime)), DateUtils
                        .FORMAT_2);
            }
            String mFileType = info.mFileType;
            if ("0".equals(mFileType) && !TextUtils.isEmpty(picShootTime)) { //图像时才加水印,并且时间不为空
                urlStr += "&file_time=" + picShootTime;
            }

            if (info.mContentType == 5) {
                urlStr = requestURL + "?user_id=" + info.mUUID + "&file_type=3&file_name=" + info.fileName
                        + "&file_iszip=1";
            }
            LogUtil.d(TAG, "wubaojie>>>sendFile: url 拼接数据地址 >>>  " + urlStr);
            URL url = new URL(urlStr);
            conn = (HttpURLConnection) url.openConnection();
            conn.setDoOutput(true);
            conn.setUseCaches(false);
            conn.setRequestMethod("POST");
            conn.setRequestProperty("Content-Type", "text/html");
            conn.setRequestProperty("Cache-Control", "no-cache");
            conn.setRequestProperty("Charsert", "UTF-8");
            conn.connect();
            conn.setConnectTimeout(30 * 1000);

        } catch (IOException e) {

            e.printStackTrace();
            conn = null;
        }
        return conn;

    }

    // Notify observers that this download's status has changed.
    private void stateChanged() {
        setChanged();
        notifyObservers();
    }

    private int submitImg() {
        //		if(info.messageType==0){
        try {
            JSONObject js = new JSONObject();
            try {
                //
                JSONObject content = new JSONObject();
                content.put("msgId", info.msgId);
                content.put("fileName", info.fileName);
                content.put("fileType", info.fileType);
                content.put("size", info.size);
                content.put("coneten", info.mContent);
                if (info.isGroup) {
                    //环信
                    js.put("group_id", info.toUser);
                    js.put("msg_sender_id", info.fromUser);
                    js.put("msg_txt", content.toString());
                    js.put("msg_type", String.valueOf(info.mContentType));
                    js.put("msg_plat", info.platForm);
                } else {
                    if (info.toUser != null) {
                        js.put("msg_recevier_id", info.toUser.split("@")[0]);
                    }
                    js.put("msg_sender_id", info.myuserid);
                    js.put("msg_txt", content.toString());
                    js.put("msg_type", String.valueOf(info.mContentType));
                    js.put("recevier_name", info.mToUserName);
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
            System.out.println("------------js：" + js.toString());
            if (TextUtils.isEmpty(info.submitUrl))
                return -1;
            HttpResponse httpConn = openConnectionPost(info.submitUrl, js.toString());
            return getHttpContent(httpConn);
        } catch (Exception e) {
            System.out.println("------------e：" + e.getMessage());
            e.printStackTrace();
        }
        //		}
        //		else if(info.messageType==1){
        //			return 0;
        //		}
        return -1;
    }

    private int getHttpContent(HttpResponse httpConn) throws IOException {
        int code = httpConn.getStatusLine().getStatusCode();
        HttpEntity entity = httpConn.getEntity();
        System.out.println("------------entity：" + entity);
        if (null != entity) {
            System.out.println("------------entity.getContentLength()：" + entity.getContentLength());
            return consumeJson((int) entity.getContentLength(), entity.getContent());
        }
        return -1;

    }

    private HttpResponse openConnectionPost(String url, String postdata) throws IOException {
        System.out.println("------------postdata：" + postdata);
        HttpClient httpClient = new DefaultHttpClient();
        HttpResponse httpConn = null;
        HttpPost httpPost = null;
        httpPost = new HttpPost(url);
        httpClient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 30 * 1000);
        httpClient.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, 20 * 1000);
        httpPost.setEntity(new StringEntity(postdata, HTTP.UTF_8));
        httpPost.addHeader("Content-type", "application/json;charset=utf-8");
        httpConn = httpClient.execute(httpPost);
        return httpConn;

    }

    private int consumeJson(int contentLength, InputStream is) throws IOException {
        int retCode = -1;
        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        StringBuilder sb = new StringBuilder();
        String line = null;
        try {
            while ((line = reader.readLine()) != null) {
                sb.append(line + "/n");
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        String value = sb.toString();// new String(sb.toString(), "UTF-8");
        System.out.println("------------value-" + value);
        try {
            JSONObject json = new JSONObject(value);
            retCode = json.getInt("code");
        } catch (Exception e) {
            e.printStackTrace();
            // }
        }
        return retCode;

    }

}
